import copy

from . import get_AttributeFactoryClasses

class AttributeFactory(object):
    def __init__(self):
        self.root_classes, self.type_classes = get_AttributeFactoryClasses()
        
    def make(self, **kwargs):
        kwargs.setdefault('type', 'Normal')
        type_name = kwargs.get('type')
        base_name = kwargs.get('base')
        new_kwargs = kwargs.get('kwargs')
        base_cls = self.root_classes[base_name]
        type_cls = self.type_classes[type_name]
        new_cls = copy.deepcopy(type_cls)
        new_cls.__bases__ = (base_cls, )
        obj = new_cls(base_cls, **new_kwargs)
        
        return obj
        
    def make_defined_from_global(self, **kwargs):
        kwargs.setdefault('kwargs', {})
        global_attrib = kwargs.get('global_attrib')
        #new_kwargs = global_attrib.__dict__.copy()
        new_kwargs = global_attrib._get_saved_attr()['attrs']
        new_kwargs.setdefault('name', global_attrib.name)
        new_kwargs.update({'id':None})
        new_kwargs.update(kwargs.get('kwargs'))
        new_kwargs.update({'root_category':global_attrib.root_category})
        if 'attribute' in new_kwargs:
            del new_kwargs['attribute']
        type_name = global_attrib.saved_class_name
        obj = self.make(base='DefinitionAttribute', type=type_name, kwargs=new_kwargs)
        
        return obj
    
    def make_patched_from_defined(self, def_attrib, **kwargs):
        type_name = def_attrib.saved_class_name
        new_kwargs = def_attrib._get_saved_attr()['attrs'].copy()
        new_kwargs.update({'id':def_attrib.name})
        new_kwargs.update({'_DefinitionAttribute_':def_attrib})
        new_kwargs.update(kwargs)
        new_kwargs.update({'root_category':def_attrib.root_category})
        #new_kwargs.update({'categories':def_attrib.categories})
        obj = self.make(base='PatchedAttribute', type=type_name, kwargs=new_kwargs)
        return obj
    
    def make_from_dict(self, d, **kwargs):
        type_name = d['saved_class_name']
        base_name = d['attrs']['base_class']
        kwargs.update({'deserialize':d})
        attribute = self.make(base=base_name, type=type_name, kwargs=kwargs)
        return attribute
